#pragma once

#include "oleidl.h"
#include "XBaseObjImpl.h"
#include <IXDropListener.h>

class XDropListenerImpl;

class XDropTargetImpl : public IUnknownImpl<IDropTarget>
{
    typedef IUnknownImpl<IDropTarget> superclass;
public:
    XDropTargetImpl(XDropListenerImpl* pListener);
    ~XDropTargetImpl();

public:
    virtual HRESULT STDMETHODCALLTYPE internalQueryInterface(REFIID riid, void **ppvObject);

public:
    virtual HRESULT STDMETHODCALLTYPE DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
    virtual HRESULT STDMETHODCALLTYPE DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
    virtual HRESULT STDMETHODCALLTYPE DragLeave(void);
    virtual HRESULT STDMETHODCALLTYPE Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);

protected:
    XDropListenerImpl*  m_pListener;
};

class XDropListenerImpl : public CXBaseObjImpl<IXDropListener>
{
    typedef CXBaseObjImpl<IXDropListener> superclass;
    DEF_SKIN_CLASS_SINGLE_INTF(XDropListenerImpl,
        superclass,
        gs_strGuidXSkin,
        IXDropListener,
        0);

public:
    XDropListenerImpl(void);
    ~XDropListenerImpl(void);

public:
    // XDropListenerImpl
    virtual HRESULT STDMETHODCALLTYPE   Enable(XWND xWnd, BOOL bEnable);
    virtual HRESULT STDMETHODCALLTYPE   RegisterCallback(IXDropCallback* pCallback);
    virtual HRESULT STDMETHODCALLTYPE   UnRegisterCallback();

public:
    // IDropListener
    HRESULT OnDragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
    HRESULT OnDragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
    HRESULT OnDragLeave(void);
    HRESULT OnDrop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);

public:
    // IXBaseObj
    virtual void STDMETHODCALLTYPE   OnFinalRelease();

protected:
    XDropEffect QueryCallbackEffect(const POINTL& pt);

protected:
    XWND                m_hWnd;
    IDropTarget*        m_pDropTarget;
    IXDropCallback*     m_pDropCallback;
};
